package br.com.pesca.bean;

import br.com.pesca.controller.UsuarioController;
import br.com.pesca.entity.Usuario;
import java.util.ArrayList;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.ValidatorException;
import javax.servlet.http.HttpServletRequest;

@ViewScoped
@ManagedBean(name = "usuarioBean")
public class UsuarioBean extends AbstractBean {

    private Usuario usuarioLogado;
    private UsuarioController usuarioController;

    private String usuario;
    private String senha;
    private String novaSenha;
    private String repitaSenha;

    private List<Usuario> usuarios;

    /**
     * Realiza a autenticação do usuário no sistema.
     *
     * @return String
     */
    public String logar() {
        FacesContext context = FacesContext.getCurrentInstance();

        Usuario login = getUsuarioController().validarUsuario(usuario, senha);

        if (login != null) {
            usuarioLogado = login;
            HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
            request.getSession().setAttribute("user", usuarioLogado);
            context.getExternalContext().getFlash().setKeepMessages(true);
            context.addMessage("sucesso", new FacesMessage(FacesMessage.SEVERITY_INFO,
                    "Sucesso!", "Usuário " + usuarioLogado.getNome() + " logado com sucesso."));
            if (usuarioLogado.isAdministrador()) {
                return "/pages/protected/admin/index.xhtml";
            }
            if (usuarioLogado.isConsultor()) {
                return "/pages/protected/consultor/index.xhtml";
            }
        }

        mensagemErro("Usuário ou Senha inválidos.");

        return null;
    }

    /**
     * Faz a validação da variável usuário no sistema.
     *
     * @param context
     * @param component
     * @param usuario
     */
    public void validaUsuario(FacesContext context, UIComponent component, String usuario) {
        List<FacesMessage> msgs = new ArrayList<>();
        if (usuario.length() < 5) {
            mensagemAtencao("O nome de usuário não pode ter menos de 5 caracteres.");
        }
        if (!msgs.isEmpty()) {
            throw new ValidatorException(msgs);
        }
    }

    /**
     * Faz a validação da variável senha no sistema.
     *
     * @param context
     * @param component
     * @param senha
     */
    public void validaSenha(FacesContext context, UIComponent component, String senha) {
        List<FacesMessage> msgs = new ArrayList<>();
        if (senha.length() < 6) {
            mensagemAtencao("A senha não pode ter menos de 6 caracteres.");
        }
        if (!msgs.isEmpty()) {
            throw new ValidatorException(msgs);
        }
    }

    /**
     * Realiza a desconexão do usuário do sistema.
     *
     * @return String
     */
    public String logout() {
        FacesContext context = FacesContext.getCurrentInstance();
        context.getExternalContext().getFlash().setKeepMessages(true);
        context.addMessage("sucesso", new FacesMessage(FacesMessage.SEVERITY_INFO, "Sucesso!", "Usuário desconectado com sucesso."));
        ((HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext()
                .getRequest()).getSession().invalidate();
        return "/pages/public/login.xhtml?faces-redirect=true";
    }

    /**
     * Método responsável por alterar a senha do usuário com perfil de
     * Administrador.
     */
    public String alterarSenhaAdministrador() {
        FacesContext context = FacesContext.getCurrentInstance();
        HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();

        try {
            if (novaSenha.equals(repitaSenha)) {
                usuarios = getUsuarioController().buscarUsuarios(Usuario.NivelDeAcesso.ADMINISTRADOR);
                for (Usuario administrador : usuarios) {
                    if (senha.equals(administrador.getSenha())) {
                        administrador.setSenha(novaSenha);
                        getUsuarioController().atualizaUsuario(administrador);
                        request.getSession().setAttribute("user", administrador);
                        context.getExternalContext().getFlash().setKeepMessages(true);
                        context.addMessage("sucesso", new FacesMessage(FacesMessage.SEVERITY_INFO,
                                "Sucesso!", "A senha de " + administrador.getNome() + " foi alterada com sucesso."));
                        return "/pages/protected/admin/index.xhtml";
                    } else {
                        mensagemAtencao("A senha atual está incorreta.");
                    }
                }
            }
        } catch (Exception e) {
            keepDialogOpen();
            mensagemAtencao("Desculpe, não foi possível alterar a senha. Tente novamente mais tarde.");
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Método responsável por alterar a senha do usuário com perfil de
     * Consultor.
     */
    public String alterarSenhaConsultor() {
        FacesContext context = FacesContext.getCurrentInstance();
        HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();

        try {
            if (novaSenha.equals(repitaSenha)) {
                usuarios = getUsuarioController().buscarUsuarios(Usuario.NivelDeAcesso.CONSULTOR);
                for (Usuario consultor : usuarios) {
                    if (senha.equals(consultor.getSenha())) {
                        consultor.setSenha(novaSenha);
                        getUsuarioController().atualizaUsuario(consultor);
                        context.getExternalContext().getFlash().setKeepMessages(true);
                        context.addMessage("sucesso", new FacesMessage(FacesMessage.SEVERITY_INFO,
                                "Sucesso!", "A senha de " + consultor.getNome() + " foi alterada com sucesso."));
                        return "/pages/protected/admin/index.xhtml";
                    } else {
                        mensagemAtencao("A senha atual está incorreta.");
                    }
                }
            }
        } catch (Exception e) {
            keepDialogOpen();
            mensagemAtencao("Desculpe, não foi possível alterar a senha. Tente novamente mais tarde.");
            e.printStackTrace();
        }
        return null;
    }

    //GETTERS AND SETTERS
    public UsuarioController getUsuarioController() {
        if (usuarioController == null) {
            usuarioController = new UsuarioController();
        }
        return usuarioController;
    }

    public String getUsuario() {
        return usuario;
    }

    public void setUsuario(String usuario) {
        this.usuario = usuario;
    }

    public String getSenha() {
        return senha;
    }

    public void setSenha(String senha) {
        this.senha = senha;
    }

    public String getNovaSenha() {
        return novaSenha;
    }

    public void setNovaSenha(String novaSenha) {
        this.novaSenha = novaSenha;
    }

    public String getRepitaSenha() {
        return repitaSenha;
    }

    public void setRepitaSenha(String repitaSenha) {
        this.repitaSenha = repitaSenha;
    }

    public Usuario getUsuarioLogado() {
        return usuarioLogado;
    }

    public void setUsuarioLogado(Usuario usuario) {
        usuarioLogado = usuario;
    }

    public List<Usuario> getUsuarios() {
        return usuarios;
    }

    public void setUsuarios(List<Usuario> usuarios) {
        this.usuarios = usuarios;
    }

}
